home *** CD-ROM | disk | FTP | other *** search
/ ShareWare OnLine 2 / ShareWare OnLine Volume 2 (CMS Software)(1993).iso / prog / spx10.zip / SPX_DOC.ZIP / SPX_SND.DOC < prev    next >
Text File  |  1993-05-05  |  10KB  |  300 lines

  1. { SPX Library Version 1.0  Copyright 1993 Scott D. Ramsay }
  2.  
  3.   The SPX_SND units it the sound and clock timer unit.   It allows
  4. the playing of digital sound through a Sound Blaster compatible card,
  5. a DAC device on the LPT port (Covox), or the PC speaker.
  6.   It also maintains eight clock timers to use for game precision.
  7.  
  8.      s_clk : array[0..3] of word;  { slow counters }
  9.      f_clk : array[0..3] of word;  { fase counters }
  10.  
  11.   The unit takes control of the computer's clock interrupt and allows
  12. the changing of its interrupt frequency.  From its regular 18.2 times per
  13. second.
  14.  
  15.   The slow counters always count down at 18.2 times a second. Regardless of
  16. the clock interrupt's rate. So, for example, the loop below will wait
  17. for 5 seconds:
  18.  
  19.    s_clk[0] := 5*18;
  20.    repeat
  21.    until s_clk[0]=0;
  22.  
  23.   Notice that there is nothing in the repeat loop.  The counters are
  24. automatically decremented.  The counter also do not roll over. They will
  25. decrement until they reach zero then stop.
  26.  
  27.   The fast counters count down according to the clock rate.  The clock rate
  28. can be changed by the following procedure:
  29.  
  30.     procedure setrate(cycles:word);
  31.  
  32.   The variable cycles indicates the number of cycles(interrupts) to generate
  33. per second.  So  setrate(18);  will restore the clock to its original rate.
  34. Setrate(1000);  will generate an interrupt 1000 times per second.  Warning some
  35. slow computers (8086/286) can not handle high clock rates.  Also conflicts
  36. may occur if running under MS Windows or OS/2.
  37.  
  38.    Here's another example:
  39.  
  40.       setrate(2048);  { set the clock rate }
  41.       f_clk[0] := 4096;
  42.       repeat
  43.       until f_clk[0]=0;
  44.  
  45.    The above example will loop for 2 seconds.
  46.  
  47.    A nice thing about the counters is that you can use them to
  48. regulate the speed of your program/game.  Lets make a VERY rough
  49. example.  Lets suppose you wrote a game that you want each 'frame'
  50. or pass to take 1 second.  Your game loop would look something
  51. like this:
  52.  
  53.      repeat
  54.        s_clk[0] := 18;
  55.        { grab user inputs }
  56.        { do game calcuations }
  57.        { setup objects for display }
  58.        { update visual screen }
  59.        while s_clk[0]<>0 do;
  60.      until game_over;
  61.  
  62.    If one pass of the loop is faster than one second, then the game
  63. will wait in the while loop until a second it up. Now depending on the
  64. speed of the computer, the number of calcuations, speed of displaying the
  65. sprites, the wait time may vary.  But the above loop will always wait
  66. at MOST one second.  Now if one pass takes longer than a second then the
  67. counter is already reached zero so there is no delay.  So the loop is
  68. running at maximum speed.
  69.  
  70.    Now the event loops for games tend to run alot faster than 1 sec.  So
  71. we would use a fast clock counter.
  72.  
  73.      setrate(3000);
  74.      repeat
  75.        f_clk[0] := 80;
  76.        { grab user inputs }
  77.        { do game calcuations }
  78.        { setup objects for display }
  79.        { update visual screen }
  80.        while f_clk[0]<>0 do;
  81.      until game_over;
  82.  
  83.    Now were all set.  We can even get fancy.  We can even automatically
  84. adjust the rate according to the cabilities of the machine;
  85.  
  86.      var
  87.        crate    : word;
  88.  
  89.      setrate(3000);
  90.      crate := 80;
  91.      repeat
  92.        f_clk[0] := crate;
  93.        { grab user inputs }
  94.        { do game calcuations }
  95.        { setup objects for display }
  96.        { update visual screen }
  97.        if (crate>0) and (f_clk[0]<10)
  98.          then dec(crate);
  99.        while f_clk[0]<>0 do;
  100.      until game_over;
  101.  
  102.    Now if the computer can't keep up with the rate (The clock comes
  103. close to timing out).  The rate is speeded up.
  104.  
  105.  
  106.    The unit uses the variable clock speeds for the playing of
  107. the audio.  To play an audio segment, the unit sets the clock rate
  108. to the sample rate of the sound.  Then at each interrupt it outputs
  109. a sample byte to directed sound port.
  110.  
  111.    Here are some ports you can use.
  112.  
  113.      $42        -  PC speaker
  114.      $378       -  LPT1 sound devices such as Covox
  115.      $210-$260  -  Sound Blaster compatible cards
  116.  
  117.    Here's how to play an 8khz raw sound file:
  118.  
  119.      Uses SPX_SND;
  120.  
  121.      var
  122.         sound : Tsound;
  123.      begin
  124.        setrate(8192);                        { Set clock to sound sample }
  125.        sound.init('Mysound.raw',$42,false);  { load the sound, use PC speaker }
  126.        sound.play(true);                     { play the sound }
  127.        repeat until not playing;             { wait for completion }
  128.        sound.done;                           { do cleanup }
  129.      end.
  130.  
  131. ───────────────────────────────────────────────────────────────────────────
  132. GLOBAL VARIABLES:
  133.  
  134.       cs:        Can stop flag, FALSE - if the current audio playing
  135.                  does not want to be interupted
  136.       playing:   TRUE - if a sound is currently playing
  137.       f_clk:     Fast clock counters
  138.       s_clk:     Slow clock counters
  139.       rate:      Current fast clock rate
  140.       cntime:    Reserved counter, Do not modify
  141.  
  142. ───────────────────────────────────────────────────────────────────────────
  143. type
  144.   Psound    = ^Tsound;
  145.   Tsound    = object
  146.  
  147.   Base sound object.  Used for playing digitized sound.
  148.  
  149. VARIABLES:
  150.         sblk:pointer     Buffer to the sound data;
  151.         size:word        Size of sound buffer;
  152.         sport:word       Port address for sound;
  153.         sb_play:boolean  Set to TRUE if (sport) is a sound blaster
  154.                          port
  155.  
  156. METHODS:
  157.  
  158.    ---------------------------------------------------
  159.    constructor tsound.init(sndfile:string;prt:word;_sb:boolean);
  160.  
  161.    Sets up the sound object.  By loading the the sound file
  162.  
  163.     SNDFILE:  DOS file name of raw sound file;
  164.     PRT:      Sound port to use for the object;
  165.     _SB:      Set to TRUE if PRT is a sound blaster port
  166.  
  167.  
  168.    ---------------------------------------------------
  169.    function tsound.loadsnd(sndfile:string;prt:word;_sb:boolean):boolean; virtual;
  170.  
  171.    Load a raw sound file into the object.
  172.  
  173.    SNDFILE: DOS file name of the raw sound file;
  174.    PRT:     Sound port to use for the object;
  175.    _SB:     Set to TRUE if PRT is a Sound Blaster port
  176.  
  177.    ---------------------------------------------------
  178.    function tsound.filesnd(var fil:file;bsize,prt:word;_sb:boolean):boolean; virtual;
  179.  
  180.    Loads a data from an open file.
  181.  
  182.    FIL:    File that contains sound data;
  183.    BSIZE:  Size of sound data in file;
  184.    PRT:    Sound port to use for the object;
  185.    _SB:    Set to TRUE if PRT is a Sound Blaster port
  186.  
  187.    NOTE: Does not close file
  188.  
  189.    ---------------------------------------------------
  190.    procedure tsound.cleansnd; virtual;
  191.  
  192.    Deallocates heap memory space for the sound.
  193.  
  194.    ---------------------------------------------------
  195.    procedure tsound.play(canstop:boolean); virtual;
  196.  
  197.    Plays the sound.
  198.  
  199.      CANSTOP:  Set to TRUE is allow other sounds to
  200.        interrupt its playing.
  201.  
  202.    ---------------------------------------------------
  203.    procedure tsound.stop; virtual;
  204.  
  205.    Stop the playing of the sound.
  206.  
  207.    ---------------------------------------------------
  208.    destructor tsound.done; virtual;
  209.  
  210.    Preforms and deallocation of the object;
  211.  
  212. ───────────────────────────────────────────────────────────────────────────
  213. type
  214.   PEmsSound = ^TEmsSound;
  215.   TEmsSound = object(Tsound)
  216.  
  217.   Expanded memory sound object.  Used for playing digitized sound.  Stores
  218.   the sound in expanded memory.
  219.  
  220. VARIABLES:
  221.  
  222.       EMSseg:     Segment address of EMS window
  223.       handle:     Handle to the ems memory block
  224.       EMSok:      Status of the EMS block, TRUE if okay
  225.  
  226. METHODS:
  227.  
  228.    ---------------------------------------------------
  229.    constructor TEmsSound.init(sndfile:string;prt:word;_sb:boolean);
  230.  
  231.    Sets up the sound object.  By loading the the sound file
  232.  
  233.     SNDFILE:  DOS file name of raw sound file;
  234.     PRT:      Sound port to use for the object;
  235.     _SB:      Set to TRUE if PRT is a sound blaster port
  236.  
  237.     ---------------------------------------------------
  238.     function TEmsSound.loadsnd(sndfile:string;prt:word;_sb:boolean):boolean; virtual;
  239.  
  240.     Load a raw sound file into the object.
  241.  
  242.     SNDFILE: DOS file name of the raw sound file;
  243.     PRT:     Sound port to use for the object;
  244.     _SB:     Set to TRUE if PRT is a Sound Blaster port
  245.  
  246.     ---------------------------------------------------
  247.     procedure TEmsSound.cleansnd; virtual;
  248.  
  249.     Deallocates expanded memory space for the sound.
  250.  
  251.     ---------------------------------------------------
  252.     procedure TEmsSound.play(canstop:boolean); virtual;
  253.  
  254.     Plays the sound.
  255.  
  256.      CANSTOP:  Set to TRUE is allow other sounds to
  257.        interrupt its playing.
  258.  
  259.     ---------------------------------------------------
  260.     destructor TEmsSound.done; virtual;
  261.  
  262.     Preforms and deallocation of the object.
  263.  
  264. ───────────────────────────────────────────────────────────────────────────
  265. function SBFindBase:word;
  266.  
  267.   Searches for a Sound Blaster compatible card.  If found, returns the port
  268.   address of the card. Returns 0 if not found.
  269.  
  270. ───────────────────────────────────────────────────────────────────────────
  271. function SBReset(BaseAddr : word) : boolean;
  272.  
  273.   Resets the sound card.  Returns TRUE if successful.
  274.  
  275.   BASEADDR:  Port address of sound card
  276.  
  277. ───────────────────────────────────────────────────────────────────────────
  278. procedure globalstop;
  279.  
  280.   Stops playback of sound.
  281.  
  282.   Note: Same as Tsound.stop and TEmsSound.stop
  283.  
  284. ───────────────────────────────────────────────────────────────────────────
  285. procedure setrate(cycles:word);
  286.  
  287.   Changes the clock rate of the computer.
  288.  
  289.   CYCLES:  Number of interrupts to generate per second
  290.  
  291. ───────────────────────────────────────────────────────────────────────────
  292. procedure wait(seconds,which:integer);
  293.  
  294.   Wait for a specified number of seconds.
  295.  
  296.   SECONDS:  Number of seconds to wait;
  297.   WHICH:    Index number of slow clock counter to use.  (0..3)
  298.  
  299. ───────────────────────────────────────────────────────────────────────────
  300.